package com.swak.exception;

import java.io.Serializable;
import java.util.Map;

import com.swak.utils.JsonMapper;
import com.swak.utils.Maps;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 系统错误码
 *
 * @author: lifeng
 * @date: 2020/3/29 11:28
 */
@Getter
@Setter
@Accessors(chain = true)
public class ErrorCode implements Serializable, Cloneable {

	private static final long serialVersionUID = 1L;

	/**
	 * 所有的错误码, ApiDoc 通过读取此字段显示所有的错误码；
	 */
	@Getter
	public static final Map<Integer, String> ErrorCodes = Maps.newOrderMap();

	/**
	 * 操作失败： 如果没有指定错误类型，默认会使用此错误码
	 */
	public static ErrorCode OPERATE_FAILURE = new ErrorCode(-1, "操作失败");
	/**
	 * 操作成功
	 */
	public static ErrorCode OPERATE_SECCESS = new ErrorCode(1, "操作成功");
	/**
	 * 参数验证失败
	 */
	public static ErrorCode BIND_ERRORS = new ErrorCode(30001, "参数验证失败");
	/**
	 * 登录失败 ---用户名和密码错误
	 */
	public static ErrorCode U_P_FAILURE = new ErrorCode(40001, "用户名不存在或者用户名和密码错误");
	/**
	 * 登录失败 ---验证码错误
	 */
	public static ErrorCode CAPTCHA_FAILURE = new ErrorCode(40002, "验证码错误");
	/**
	 * 登录失败 ---账户锁定
	 */
	public static ErrorCode ACCOUNT_ANOMALY = new ErrorCode(40003, "账户异常");
	/**
	 * 访问受限 ---无权限
	 */
	public static ErrorCode ACCESS_DENIED = new ErrorCode(40004, "访问受限,请登录或联系管理员授权");
	/**
	 * 访问受限 ---没登录（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_USER = new ErrorCode(40005, "访问受限,请登录");
	/**
	 * 访问受限 ---没登录（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_TENANT = new ErrorCode(40005, "访问受限,请登录");
	/**
	 * 访问受限 ---没登录（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_AUTHENTICATED = new ErrorCode(40006, "操作受限,请输入密码认证");
	/**
	 * 访问受限 ---必须是微信用户（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_BIND_WX = new ErrorCode(40007, "操作受限,必须绑定微信用户");
	/**
	 * 访问受限 ---必须是微信用户（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_OPEN_WX = new ErrorCode(40008, "操作受限,必须在微信客户端打开");
	/**
	 * 访问受限 ---必须是微信用户（没登陆和没授权是两个不同的问题）
	 */
	public static ErrorCode NO_SUBSCRIBE_WX = new ErrorCode(40009, "操作受限,必须是关注微信");
	/**
	 * 访问受限 ---请重新发起登录操作（一般页面收到这个请求后重新发起请求）
	 */
	public static ErrorCode REDIRECT_LOGIN = new ErrorCode(40010, "重新发起登录操作");
	/**
	 * Token 错误
	 */
	public static ErrorCode TOKEN_ERROR = new ErrorCode(40011, "token 失效或者过期");
	/**
	 * 路由没有找到
	 */
	public static ErrorCode PATH_NOT_FOUNT = new ErrorCode(40012, "路由没有找到");
	/**
	 * 路由没有找到
	 */
	public static ErrorCode OAUTH_NOT_FOUNT = new ErrorCode(40013, "未识别到授权信息");
	/**
	 * 用户已经存在
	 */
	public static ErrorCode USER_HAS_EXISTS = new ErrorCode(40015, "用户已经存在");
	/**
	 * 密码登陆超过次数
	 */
	public static ErrorCode PASSWD_LOGIN_EXCEED = new ErrorCode(40016, "密码登陆超过次数");
	/**
	 * 用户的手机号不存在
	 */
	public static ErrorCode USER_PHONE_NOT_EXISTS = new ErrorCode(40017, "用户的手机号不存在");
	/**
	 * 用户的手机号不存在
	 */
	public static ErrorCode USER_PHONE_BINDED = new ErrorCode(40018, "手机号已经绑定");
	/**
	 * 服务器错误
	 */
	public static ErrorCode SERVER_ERROR = new ErrorCode(50000, "服务器错误");
	/**
	 * 错误code
	 */
	private final int code;

	/**
	 * 错误描述
	 */
	private final String msg;

	public ErrorCode(int code, String msg) {
		this.code = code;
		this.msg = msg;
		ErrorCodes.put(code, msg);
	}

	public String toJson() {
		return JsonMapper.toJson(this);
	}

	@Override
	public ErrorCode clone() throws CloneNotSupportedException {
		return (ErrorCode) super.clone();
	}

	public static ErrorCode of(int code, String msg) {
		return new ErrorCode(code, msg);
	}
}